<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>心脏病预测系统</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            text-align: center;
            margin-bottom: 30px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            color: #666;
            font-weight: bold;
        }
        input, select {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
            font-size: 16px;
            margin-bottom: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 20px;
            border-radius: 4px;
            display: none;
        }
        .result.positive {
            background-color: #ffebee;
            border: 1px solid #ffcdd2;
        }
        .result.negative {
            background-color: #e8f5e9;
            border: 1px solid #c8e6c9;
        }
        .result h2 {
            margin-top: 0;
            color: #333;
        }
        .result p {
            margin: 10px 0;
            color: #666;
        }
        .loading {
            display: none;
            text-align: center;
            padding: 20px;
        }
        .error {
            display: none;
            color: red;
            text-align: center;
            padding: 20px;
        }
        .help-text {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        .history-section {
            margin-top: 30px;
            padding: 20px;
            border-radius: 4px;
            border: 1px solid #ddd;
            background-color: #f9f9f9;
        }
        .history-section h2 {
            margin-top: 0;
            color: #333;
        }
        .history-section button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
            font-size: 16px;
        }
        .history-section button:hover {
            background-color: #45a049;
        }
        .history-loading {
            display: none;
            text-align: center;
            padding: 20px;
        }
        .history-error {
            display: none;
            color: red;
            text-align: center;
            padding: 20px;
        }
        .history-table {
            width: 100%;
            margin-top: 20px;
            border-collapse: collapse;
        }
        .history-table th, .history-table td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        .history-table th {
            background-color: #f2f2f2;
        }
        .history-table tbody tr:nth-child(even) {
            background-color: #f9f9f9;
        }
        .id-section {
            margin-bottom: 25px;
            padding: 15px;
            background-color: #f0f8ff;
            border-radius: 4px;
            border: 1px solid #b3d8ff;
        }
        .id-form {
            display: flex;
            gap: 10px;
        }
        .id-input {
            flex-grow: 1;
        }
        .id-button {
            width: auto;
        }
        .tabs {
            display: flex;
            margin-bottom: 20px;
        }
        .tab {
            padding: 10px 20px;
            background-color: #f1f1f1;
            cursor: pointer;
            margin-right: 5px;
            border-radius: 4px 4px 0 0;
        }
        .tab.active {
            background-color: #4CAF50;
            color: white;
        }
        .user-id-text {
            color: #2196F3;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>心脏病预测系统</h1>
        
        <div class="id-section">
            <h3>个人ID管理</h3>
            <p>请输入您的个人ID，方便查询历史预测结果</p>
            <div class="id-form">
                <input type="text" id="userId" class="id-input" placeholder="请输入您的个人ID (例如: 身份证后六位)">
                <button id="loadUserDataBtn" class="id-button">查询记录</button>
            </div>
            <div id="currentUserId" style="margin-top: 10px; display: none;">
                当前ID: <span class="user-id-text"></span>
            </div>
        </div>
        
        <div class="tabs">
            <div class="tab active" id="newPredictionTab">新预测</div>
            <div class="tab" id="historyTab">历史记录</div>
        </div>
        
        <div id="newPredictionSection">
            <form id="predictionForm">
                <input type="hidden" id="userIdHidden" name="user_id">
                
                <div class="form-group">
                    <label for="age">年龄</label>
                    <input type="number" id="age" name="age" required min="1" max="120">
                    <div class="help-text">请输入年龄（1-120岁）</div>
                </div>

                <div class="form-group">
                    <label for="sex">性别</label>
                    <select id="sex" name="sex" required>
                        <option value="">请选择</option>
                        <option value="0">女性</option>
                        <option value="1">男性</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="cp">胸痛类型</label>
                    <select id="cp" name="cp" required>
                        <option value="">请选择</option>
                        <option value="0">典型心绞痛</option>
                        <option value="1">非典型心绞痛</option>
                        <option value="2">非心绞痛</option>
                        <option value="3">无症状</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="trestbps">静息血压 (mmHg)</label>
                    <input type="number" id="trestbps" name="trestbps" required min="90" max="200">
                    <div class="help-text">请输入静息血压值（90-200 mmHg）</div>
                </div>

                <div class="form-group">
                    <label for="chol">胆固醇 (mg/dl)</label>
                    <input type="number" id="chol" name="chol" required min="120" max="600">
                    <div class="help-text">请输入胆固醇值（120-600 mg/dl）</div>
                </div>

                <div class="form-group">
                    <label for="fbs">空腹血糖</label>
                    <select id="fbs" name="fbs" required>
                        <option value="">请选择</option>
                        <option value="0">≤ 120 mg/dl</option>
                        <option value="1">> 120 mg/dl</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="restecg">心电图结果</label>
                    <select id="restecg" name="restecg" required>
                        <option value="">请选择</option>
                        <option value="0">正常</option>
                        <option value="1">ST-T波异常</option>
                        <option value="2">左心室肥大</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="thalach">最大心率</label>
                    <input type="number" id="thalach" name="thalach" required min="70" max="200">
                    <div class="help-text">请输入最大心率值（70-200 bpm）</div>
                </div>

                <div class="form-group">
                    <label for="exang">运动诱发心绞痛</label>
                    <select id="exang" name="exang" required>
                        <option value="">请选择</option>
                        <option value="0">否</option>
                        <option value="1">是</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="oldpeak">ST压低</label>
                    <input type="number" id="oldpeak" name="oldpeak" required min="0" max="6.2" step="0.1">
                    <div class="help-text">请输入ST压低值（0-6.2）</div>
                </div>

                <div class="form-group">
                    <label for="slope">心电图ST段斜率</label>
                    <select id="slope" name="slope" required>
                        <option value="">请选择</option>
                        <option value="0">上升</option>
                        <option value="1">平坦</option>
                        <option value="2">下降</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="ca">荧光检查显示的主要血管数</label>
                    <select id="ca" name="ca" required>
                        <option value="">请选择</option>
                        <option value="0">0个</option>
                        <option value="1">1个</option>
                        <option value="2">2个</option>
                        <option value="3">3个</option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="thal">地中海贫血</label>
                    <select id="thal" name="thal" required>
                        <option value="">请选择</option>
                        <option value="0">正常</option>
                        <option value="1">固定缺陷</option>
                        <option value="2">可逆缺陷</option>
                    </select>
                </div>

                <button type="submit">预测</button>
            </form>

            <div class="loading">预测中...</div>
            <div class="error"></div>
            <div class="result">
                <h2>预测结果</h2>
                <p class="prediction-text"></p>
                <p class="probability-text"></p>
            </div>
        </div>
        
        <div id="historySection" style="display: none;">
            <h2>历史预测记录</h2>
            <div id="historyUserInfo" style="margin-bottom: 15px; padding: 10px; background-color: #e8f5e9; border-radius: 4px; display: none;">
                <span style="font-weight: bold;">用户ID: </span><span id="historyUserId" style="color: #2196F3; font-weight: bold;"></span>
                <span style="margin-left: 20px; font-weight: bold;">总记录数: </span><span id="historyTotalCount"></span>
            </div>
            <div class="history-loading" style="display: none;">加载中...</div>
            <div class="history-error" style="display: none;"></div>
            <table id="historyTable" style="display: none; width: 100%; margin-top: 20px; border-collapse: collapse;">
                <thead>
                    <tr>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">序号</th>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">用户ID</th>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">预测结果</th>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">预测概率</th>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">预测时间</th>
                        <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">详情</th>
                    </tr>
                </thead>
                <tbody id="historyTableBody">
                </tbody>
            </table>
        </div>
    </div>

    <script>
        // 切换标签页
        document.getElementById('newPredictionTab').addEventListener('click', function() {
            this.classList.add('active');
            document.getElementById('historyTab').classList.remove('active');
            document.getElementById('newPredictionSection').style.display = 'block';
            document.getElementById('historySection').style.display = 'none';
        });
        
        document.getElementById('historyTab').addEventListener('click', function() {
            this.classList.add('active');
            document.getElementById('newPredictionTab').classList.remove('active');
            document.getElementById('newPredictionSection').style.display = 'none';
            document.getElementById('historySection').style.display = 'block';
            
            // 如果已设置用户ID，自动加载历史记录
            const userId = document.getElementById('userIdHidden').value;
            if (userId) {
                loadUserPredictions(userId);
            }
        });
        
        // 保存用户ID并查询历史记录
        document.getElementById('loadUserDataBtn').addEventListener('click', function() {
            const userId = document.getElementById('userId').value.trim();
            if (!userId) {
                alert('请输入有效的用户ID');
                return;
            }
            
            // 保存用户ID到表单中
            document.getElementById('userIdHidden').value = userId;
            
            // 显示当前用户ID
            document.getElementById('currentUserId').style.display = 'block';
            document.querySelector('#currentUserId .user-id-text').textContent = userId;
            
            // 自动切换到历史记录标签页并加载数据
            document.getElementById('historyTab').click();
        });
        
        // 加载用户历史预测记录
        function loadUserPredictions(userId) {
            const historyLoading = document.querySelector('.history-loading');
            const historyError = document.querySelector('.history-error');
            const historyTable = document.getElementById('historyTable');
            const historyTableBody = document.getElementById('historyTableBody');
            
            // 显示加载状态
            historyLoading.style.display = 'block';
            historyError.style.display = 'none';
            historyTable.style.display = 'none';
            
            try {
                // 获取历史记录
                axios.get(`http://127.0.0.1:5000/api/predictions/user/${userId}`)
                    .then(response => {
                        console.log('用户历史记录响应:', response.data);
                        
                        // 清空表格
                        historyTableBody.innerHTML = '';
                        
                        if (response.data.records && response.data.records.length > 0) {
                            // 显示用户信息
                            document.getElementById('historyUserInfo').style.display = 'block';
                            document.getElementById('historyUserId').textContent = response.data.user_id;
                            document.getElementById('historyTotalCount').textContent = response.data.total_records;
                            
                            // 填充表格
                            response.data.records.forEach((record, index) => {
                                const row = document.createElement('tr');
                                
                                // 序号列
                                const seqCell = document.createElement('td');
                                seqCell.style.border = '1px solid #ddd';
                                seqCell.style.padding = '8px';
                                seqCell.textContent = index + 1;
                                
                                // 用户ID列
                                const userIdCell = document.createElement('td');
                                userIdCell.style.border = '1px solid #ddd';
                                userIdCell.style.padding = '8px';
                                userIdCell.textContent = record.user_id;
                                userIdCell.style.fontWeight = 'bold';
                                userIdCell.style.color = '#2196F3';
                                
                                const predictionCell = document.createElement('td');
                                predictionCell.style.border = '1px solid #ddd';
                                predictionCell.style.padding = '8px';
                                predictionCell.textContent = record.prediction === 1 ? '患有心脏病' : '无心脏病';
                                predictionCell.style.color = record.prediction === 1 ? '#d32f2f' : '#388e3c';
                                
                                const probabilityCell = document.createElement('td');
                                probabilityCell.style.border = '1px solid #ddd';
                                probabilityCell.style.padding = '8px';
                                probabilityCell.textContent = `${(record.probability * 100).toFixed(2)}%`;
                                
                                const timestampCell = document.createElement('td');
                                timestampCell.style.border = '1px solid #ddd';
                                timestampCell.style.padding = '8px';
                                // 将ISO时间格式转换为本地时间
                                const date = new Date(record.timestamp);
                                timestampCell.textContent = date.toLocaleString();
                                
                                // 添加详情按钮
                                const detailsCell = document.createElement('td');
                                detailsCell.style.border = '1px solid #ddd';
                                detailsCell.style.padding = '8px';
                                
                                const detailsButton = document.createElement('button');
                                detailsButton.textContent = '查看详情';
                                detailsButton.style.width = 'auto';
                                detailsButton.style.padding = '5px 10px';
                                detailsButton.style.fontSize = '12px';
                                
                                detailsButton.addEventListener('click', function() {
                                    // 填充表单数据
                                    fillFormWithHistoricalData(record.input_data);
                                    // 切换到预测标签页
                                    document.getElementById('newPredictionTab').click();
                                });
                                
                                detailsCell.appendChild(detailsButton);
                                
                                // 将单元格添加到行
                                row.appendChild(seqCell);
                                row.appendChild(userIdCell);
                                row.appendChild(predictionCell);
                                row.appendChild(probabilityCell);
                                row.appendChild(timestampCell);
                                row.appendChild(detailsCell);
                                
                                // 将行添加到表格
                                historyTableBody.appendChild(row);
                            });
                            
                            // 显示表格
                            historyTable.style.display = 'table';
                        } else {
                            // 没有记录
                            historyError.style.display = 'block';
                            historyError.textContent = `未找到用户ID为${userId}的预测记录`;
                        }
                    })
                    .catch(err => {
                        console.error('获取用户历史记录错误:', err);
                        historyError.style.display = 'block';
                        historyError.textContent = err.response?.data?.message || '加载历史记录失败，请重试';
                    })
                    .finally(() => {
                        historyLoading.style.display = 'none';
                    });
            } catch (err) {
                console.error('获取历史记录错误:', err);
                historyError.style.display = 'block';
                historyError.textContent = '加载历史记录失败，请重试';
                historyLoading.style.display = 'none';
            }
        }
        
        // 填充表单数据
        function fillFormWithHistoricalData(data) {
            document.getElementById('age').value = data.age;
            document.getElementById('sex').value = data.sex;
            document.getElementById('cp').value = data.cp;
            document.getElementById('trestbps').value = data.trestbps;
            document.getElementById('chol').value = data.chol;
            document.getElementById('fbs').value = data.fbs;
            document.getElementById('restecg').value = data.restecg;
            document.getElementById('thalach').value = data.thalach;
            document.getElementById('exang').value = data.exang;
            document.getElementById('oldpeak').value = data.oldpeak;
            document.getElementById('slope').value = data.slope;
            document.getElementById('ca').value = data.ca;
            document.getElementById('thal').value = data.thal;
        }

        document.getElementById('predictionForm').addEventListener('submit', async function(e) {
            e.preventDefault();
            
            const form = e.target;
            const loading = document.querySelector('.loading');
            const error = document.querySelector('.error');
            const result = document.querySelector('.result');
            
            // 显示加载状态
            loading.style.display = 'block';
            error.style.display = 'none';
            result.style.display = 'none';
            
            // 收集表单数据
            const formData = new FormData(form);
            const data = {};
            
            // 验证并转换数据
            try {
                formData.forEach((value, key) => {
                    // 如果是user_id字段且为空，跳过
                    if (key === 'user_id' && !value) {
                        return;
                    }
                    
                    // 确保所有必需的字段都存在
                    if (!value) {
                        throw new Error(`请填写 ${key} 字段`);
                    }
                    
                    // 根据字段类型转换数据
                    if (['age', 'trestbps', 'chol', 'thalach', 'oldpeak'].includes(key)) {
                        data[key] = parseFloat(value);
                        if (isNaN(data[key])) {
                            throw new Error(`${key} 必须是数字`);
                        }
                    } else if (key === 'user_id') {
                        // 保留user_id为字符串
                        data[key] = value;
                    } else {
                        data[key] = parseInt(value);
                        if (isNaN(data[key])) {
                            throw new Error(`${key} 必须是整数`);
                        }
                    }
                });
                
                // 验证数值范围
                if (data.age < 1 || data.age > 120) {
                    throw new Error('年龄必须在1-120岁之间');
                }
                if (data.trestbps < 90 || data.trestbps > 200) {
                    throw new Error('静息血压必须在90-200 mmHg之间');
                }
                if (data.chol < 120 || data.chol > 600) {
                    throw new Error('胆固醇必须在120-600 mg/dl之间');
                }
                if (data.thalach < 70 || data.thalach > 200) {
                    throw new Error('最大心率必须在70-200 bpm之间');
                }
                if (data.oldpeak < 0 || data.oldpeak > 6.2) {
                    throw new Error('ST压低必须在0-6.2之间');
                }
                
                console.log('发送的数据:', data);  // 调试日志
                
                // 发送预测请求
                const response = await axios.post('http://127.0.0.1:5000/api/predict', data, {
                    headers: {
                        'Content-Type': 'application/json'
                    }
                });
                console.log('接收到的响应:', response.data);  // 调试日志
                
                // 显示结果
                result.style.display = 'block';
                result.className = `result ${response.data.prediction === 1 ? 'positive' : 'negative'}`;
                
                const predictionText = document.querySelector('.prediction-text');
                const probabilityText = document.querySelector('.probability-text');
                
                predictionText.textContent = response.data.prediction === 1 
                    ? '预测结果：您可能患有心脏病'
                    : '预测结果：您可能没有心脏病';
                
                probabilityText.textContent = `预测概率：${(response.data.probability * 100).toFixed(2)}%`;
                
                // 如果用户提供了ID，自动切换到历史记录标签并刷新
                if (data.user_id) {
                    // 给用户一点时间来查看结果，然后切换到历史记录
                    setTimeout(() => {
                        document.getElementById('historyTab').click();
                    }, 2000);
                }
                
            } catch (err) {
                console.error('预测错误:', err);  // 调试日志
                error.style.display = 'block';
                error.textContent = err.response?.data?.message || err.message || '预测失败，请重试';
            } finally {
                loading.style.display = 'none';
            }
        });
    </script>
</body>
</html> 